package org.wk.common.qiniu;


import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.model.FetchRet;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.wk.core.common.tool.GeneratorStringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 *
 */
public class UploadManagerFacade {
    private static Logger logger = LogManager.getLogger(UploadManagerFacade.class);

    public static void main(String[] args){
        String localFilePath = "e:\\timg.jpg";
        StringBuffer targetFileName = new StringBuffer();
        targetFileName.append(GeneratorStringUtils.uuidStr());
        targetFileName.append(".jpg");
        String contentType = "image";
        boolean isTest = true;
        try {
            logger.info(targetFileName.toString());
            Response response = upload(localFilePath, contentType, targetFileName.toString(), isTest);
            logger.info(JSONObject.toJSON(response));
            logger.info(response.isOK());
            logger.info(response.jsonToMap().get("key"));
            logger.info(BucketEnum.IMAGE_BUCKET_TEST.getDomain()+"/"+response.jsonToMap().get("key"));
        } catch (Exception e) {
            e.printStackTrace();
        }

        String localTempDir = Paths.get("/Users/FENGCUIJIE/Downloads/temp", BucketEnum.VIDEO_BUCKET_TEST.getNameSpace()).toString();
        System.out.println(localTempDir);

    }

    /**
     * 资源路由
     * @param contentType 文件类型
     * @param isTest 是否走测试命名空间
     * @return
     */
    private static BucketEnum route(String contentType, boolean isTest) {
        if(isTest){
            switch(contentType){
                case "image": return BucketEnum.IMAGE_BUCKET_TEST;
                case "audio": return BucketEnum.AUDIO_BUCKET_TEST;
                case "video": return BucketEnum.VIDEO_BUCKET_TEST;
                case "document": return BucketEnum.DOCUMENT_BUCKET_TEST;
                default:  return BucketEnum.IMAGE_BUCKET_TEST;
            }
        } else {
            switch(contentType){
                case "image": return BucketEnum.IMAGE_BUCKET;
                case "audio": return BucketEnum.AUDIO_BUCKET;
                case "video": return BucketEnum.VIDEO_BUCKET;
                case "document": return BucketEnum.DOCUMENT_BUCKET;
                default:  return BucketEnum.IMAGE_BUCKET;
            }
        }
    }

    /**
     * @param file   文件 File
     * @param contentType 上传文件类型  image,audio,video,document
     * @param targetFileName 文件从命名
     * @return Map<String,String>  statusCode: '0' 成功  '-1' 失败
     *                              fileName: 文件名
     *                              fileUrl: 文件的访问路径
     * @throws Exception
     */
    public static Map<String,String> upload(File file, String contentType, String targetFileName,long size) throws Exception {
        boolean isTest = true;
        Response response = null;
        //如果文件大小超过10M 分片操作
        if (size>1048576){
            response = uploadbreakpoint(file,contentType,targetFileName,isTest);
        }else{
            response = upload(file,contentType,targetFileName,isTest);
        }

        Map<String, String> resMap = new HashMap<>();
        if (response.isOK()){
            resMap.put("statusCode", "0");
            String fileName = response.jsonToMap().get("key").toString();
            resMap.put("fileName",fileName);
            StringBuffer sb = new StringBuffer();

            String urlBase = route(contentType, isTest).getDomain();
            sb.append(urlBase).append("/").append(fileName);
            resMap.put("fileUrl",sb.toString());
        }else {
            resMap.put("statusCode", "-1");
        }
        return resMap;

    }

    /**
     * 文件上传
     * @param file 文件
     * @param contentType 文件类型
     * @param isTest
     * @return
     * @throws Exception
     */
    public static Response upload(File file, String contentType, String targetFileName, boolean isTest) throws Exception {
        // 路由到资源空间
        String bucket = route(contentType, isTest).getNameSpace();
        String token = ClientBuilder.token(bucket);
        return ClientBuilder.createUploadManager().put(file, targetFileName, token);
    }

    /**
     * 文件上传
     * @param localFilePath 本地文件路径
     * @param contentType 文件类型
     * @param targetFileName 目标文件名称
     * @param isTest
     * @return
     * @throws Exception
     */
    public static Response upload(String localFilePath, String contentType, String targetFileName, boolean isTest) throws Exception {
        // 路由到资源空间
        String bucket = route(contentType, isTest).getNameSpace();
        String token = ClientBuilder.token(bucket);
        return ClientBuilder.createUploadManager().put(localFilePath, targetFileName, token);
    }

    public static Map<String,String> upload(byte[] data, String contentType, String targetFileName, boolean isTest) throws IOException {
        try {
            BucketEnum bucketEnum = route(contentType, isTest);

            String token = ClientBuilder.token(bucketEnum.getNameSpace());
            //调用put方法上传
            Response response = ClientBuilder.createUploadManager().put(data, targetFileName, token);
            //打印返回的信息
            System.out.println(response.bodyString());
            Map<String, String> resMap = new HashMap<>();
            if (response.isOK()){
                resMap.put("statusCode", "0");
                String fileName = response.jsonToMap().get("key").toString();
                resMap.put("fileName",fileName);
                StringBuffer sb = new StringBuffer();
                sb.append(bucketEnum.getDomain()).append("/").append(fileName);
                resMap.put("fileUrl",sb.toString());
            }else {
                resMap.put("statusCode", "-1");
            }
            return resMap;
        } catch (QiniuException e) {
            Response r = e.response;
            // 请求失败时打印的异常的信息
            System.out.println(r.toString());
            try {
                //响应的文本信息
                System.out.println(r.bodyString());
//                return r.bodyString();
            } catch (QiniuException e1) {
                //ignore
            }
        }
        return null;
    }

    /**
     * @Title		: uploadFile
     * @Param		: @param url  网络路径
     * @Param		: @param name 名称
     * @Param		: @param bucktName
     * @Param		: @return
     * @Param		: @throws IOException
     * @Return Type 	：String
     * @Description	: 抓取网络图片
     */
    public static Map<String,String> upload(String url, String contentType) throws IOException {
        try {
            boolean isTest = true;
            BucketEnum bucketEnum = route(contentType, isTest);
            //调用put方法上传
            String targetFileName = GeneratorStringUtils.uuidStr();
            FetchRet fetchRet = ClientBuilder.createBucketManager().fetch(url, bucketEnum.getNameSpace(), targetFileName);
            //打印返回的信息
            String key = fetchRet.key;
            System.out.println(key);

            Map<String, String> resMap = new HashMap<>();
            if (!Strings.isNullOrEmpty(key)){
                resMap.put("statusCode", "0");
                resMap.put("fileName",key);
                StringBuffer sb = new StringBuffer();
                sb.append(bucketEnum.getDomain()).append("/").append(key);
                resMap.put("fileUrl",sb.toString());
            }else {
                resMap.put("statusCode", "-1");
            }
            return resMap;

        } catch (QiniuException e) {
            Response r = e.response;
            // 请求失败时打印的异常的信息
            System.out.println(r.toString());
            try {
                //响应的文本信息
                System.out.println(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        }
        return null;
    }
    /**
     * 断点续传
     * @param localFilePath 本地文件路径
     * @param localDir 本地临时文件目录
     * @param contentType 文件类型
     * @param targetFileName 目标文件名称
     * @param isTest
     * @return
     * @throws Exception
     */
    public static Response upload(String localFilePath, String localDir, String contentType, String targetFileName, boolean isTest) throws Exception {
        // 路由到资源空间
        String bucket = route(contentType, isTest).getNameSpace();
        String localTempDir = Paths.get(localDir, bucket).toString();
        String token = ClientBuilder.token(bucket);
        return ClientBuilder.createRecorderUploadManager(localTempDir).put(localFilePath, targetFileName, token);
    }
    public static Response uploadbreakpoint(File file, String contentType, String targetFileName, boolean isTest) throws Exception {
        // 路由到资源空间
        String bucket = route(contentType, isTest).getNameSpace();
        String localDir = System.getProperty("java.io.tmpdir");
        String localTempDir = Paths.get(localDir, bucket).toString();
        String token = ClientBuilder.token(bucket);
        return ClientBuilder.createRecorderUploadManager(localTempDir).put(file, targetFileName, token);
    }

}
